package com.ssy.lingxi.contract.serviceimpl;

import cn.hutool.core.date.DateUtil;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.contract.api.model.vo.request.PurchaseInquiryAddVO;
import com.ssy.lingxi.contract.constant.Constants;
import com.ssy.lingxi.contract.entity.PurchaseInquiryDO;
import com.ssy.lingxi.contract.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.contract.model.vo.common.request.PurchaseInquiryPageVO;
import com.ssy.lingxi.contract.model.vo.common.response.PurchaseInquiryQueryVO;
import com.ssy.lingxi.contract.repository.PurchaseInquiryRepository;
import com.ssy.lingxi.contract.service.IFeignService;
import com.ssy.lingxi.contract.service.IPurchaseInquiryService;
import com.ssy.lingxi.message.api.constant.MessageTemplateCode;
import com.ssy.lingxi.message.api.vo.request.SystemMessageRequest;
import com.ssy.lingxi.report.api.enums.ContractManageOperateTypeEnum;
import com.ssy.lingxi.report.api.enums.OperateDataSourceEnum;
import com.ssy.lingxi.report.api.vo.request.OperateNoticeVO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 采购询价合同接口实现
 * @author 伍将
 * @date 2021/3/4
 * @version 2.0.0
 */
@Service
public class PurchaseInquiryServiceImpl implements IPurchaseInquiryService {

    @Resource
    private PurchaseInquiryRepository repository;
    @Resource
    private IFeignService feignService;
//    @Resource
//    IRabbitMQUtils rabbitMQUtils;

    /**
     * 批量新增采购询价合同
     * @author 伍将
     * @date 2021/3/4
     * @param addVOList: 新增请求参数
     * @return 操作结果
     **/
    @Transactional
    @Override
    public Wrapper<Void> addList(List<PurchaseInquiryAddVO> addVOList) {

        if (null != addVOList && addVOList.size() > 0) {

            // 验证新增数据是否已存在
            for (PurchaseInquiryAddVO addVO : addVOList) {
                Boolean isExists = repository.existsByDemandMemberIdAndDemandRoleIdAndAwardMemberIdAndAwardRoleIdAndDemandId(
                        addVO.getDemandMemberId(), addVO.getDemandRoleId(), addVO.getAwardMemberId(), addVO.getAwardRoleId(), addVO.getDemandId());
                if (isExists) {
                    throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_INQUIRY_IS_EXIST);
                }
            }

            // 组装新增对象
            List<PurchaseInquiryDO> addList = addVOList.stream().map(o -> {
                PurchaseInquiryDO entity = new PurchaseInquiryDO();
                entity.setDemandMemberId(o.getDemandMemberId());
                entity.setDemandRoleId(o.getDemandRoleId());
                entity.setDemandId(o.getDemandId());
                entity.setDemandNO(o.getDemandNO());
                entity.setDemandAbstract(o.getDemandAbstract());
                entity.setDemandPublishTime(o.getDemandPublishTime());
                entity.setAwardMemberId(o.getAwardMemberId());
                entity.setAwardRoleId(o.getAwardRoleId());
                entity.setAwardName(o.getAwardName());
                entity.setAwardTime(o.getAwardTime());
                entity.setAwardAmount(o.getAwardAmount());
                entity.setInnerStatus(o.getInnerStatus());
                entity.setOuterStatus(o.getOuterStatus());
                entity.setIsCreate(CommonBooleanEnum.NO.getCode());
                entity.setCreateTime(System.currentTimeMillis());
                entity.setUpdateTime(System.currentTimeMillis());
                entity.setTurn(o.getTurn());
                entity.setQuotedPriceOrderId(o.getId());
                entity.setQuotedPriceOrderNo(o.getOrderNo());
                entity.setPurchaseType(o.getPurchaseType());
                return entity;
            }).collect(Collectors.toList());

            // 保存采购询价合同
            repository.saveAll(addList);
            //采购询价提交+系统操作通知
            List<OperateNoticeVO> noticeVOS = addList.stream().map(inquiry -> {
                OperateNoticeVO noticeVO = new OperateNoticeVO();
                noticeVO.setMemberId(inquiry.getDemandMemberId());
                noticeVO.setRoleId(inquiry.getDemandRoleId());
                noticeVO.setDataSource(OperateDataSourceEnum.CONTRACT_MANAGE.getCode());
                noticeVO.setIncreaseOperateType(ContractManageOperateTypeEnum.TO_BE_CREATE_INQUIRY.getCode());
                noticeVO.setIncreaseCount(Constants.SYS_OPERATE_NOTICE_COUNT);
                noticeVO.setIncreaseTitle(inquiry.getDemandAbstract());
                noticeVO.setIncreaseDataId(inquiry.getId());
                return noticeVO;
            }).collect(Collectors.toList());
            feignService.addSysOperateNoticeToMQ(noticeVOS);
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    //发送消息
                    List<SystemMessageRequest> msgList = addVOList.stream().map(o -> {
                        SystemMessageRequest request = new SystemMessageRequest();
                        request.setMemberId(o.getDemandMemberId());
                        request.setRoleId(o.getDemandRoleId());
                        request.setMessageNotice(MessageTemplateCode.contract_manage_purchase_create);
                        request.setParams(Stream.of(o.getDemandNO(), o.getDemandAbstract()).collect(Collectors.toList()));
                        return request;
                    }).collect(Collectors.toList());
                    feignService.batchSendSystemMessage(msgList);
                }
            });
        }

        return Wrapper.success();
    }

    /**
     * 分页查询待创建采购询价合同
     * @author 伍将
     * @date 2021/3/4
     * @param user: 当前登录用户
     * @param pageVO: 分页请求参数
     * @return 操作结果
     **/
    @Override
    public Wrapper<PageData<PurchaseInquiryQueryVO>> pageToBeCreate(UserLoginCacheDTO user, PurchaseInquiryPageVO pageVO) {

        // 组装查询条件
        Specification<PurchaseInquiryDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("demandMemberId").as(Long.class), user.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("demandRoleId").as(Long.class), user.getMemberRoleId()));
            list.add(criteriaBuilder.equal(root.get("isCreate").as(Long.class), CommonBooleanEnum.NO.getCode()));
            if (StringUtils.hasLength(pageVO.getStartTime())) {
                list.add(criteriaBuilder.greaterThan(root.get("awardTime").as(Long.class), DateUtil.parse(pageVO.getStartTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getEndTime())) {
                list.add(criteriaBuilder.lessThan(root.get("awardTime").as(Long.class), DateUtil.parse(pageVO.getEndTime()).getTime()));
            }
            if (StringUtils.hasLength(pageVO.getDemandNO())) {
                list.add(criteriaBuilder.like(root.get("demandNO").as(String.class), "%" + pageVO.getDemandNO().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getDemandAbstract())) {
                list.add(criteriaBuilder.like(root.get("demandAbstract").as(String.class), "%" + pageVO.getDemandAbstract().trim() + "%"));
            }
            if (StringUtils.hasLength(pageVO.getAwardName())) {
                list.add(criteriaBuilder.like(root.get("awardName").as(String.class), "%" + pageVO.getAwardName().trim() + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("awardTime").descending());

        Page<PurchaseInquiryDO> result = repository.findAll(spec, page);
        List<PurchaseInquiryQueryVO> resultList = result.getContent().stream().map(o -> {
            PurchaseInquiryQueryVO entity = new PurchaseInquiryQueryVO();
            entity.setId(o.getId());
            entity.setDemandId(o.getDemandId());
            entity.setDemandNO(o.getDemandNO());
            entity.setDemandAbstract(o.getDemandAbstract());
            entity.setDemandPublishTime(DateUtil.format(DateUtil.date(o.getDemandPublishTime()), "yyyy-MM-dd HH:mm"));
            entity.setAwardMemberId(o.getAwardMemberId());
            entity.setAwardRoleId(o.getAwardRoleId());
            entity.setAwardName(o.getAwardName());
            entity.setAwardTime(DateUtil.format(DateUtil.date(o.getAwardTime()), "yyyy-MM-dd HH:mm"));
            entity.setAwardAmount(o.getAwardAmount());
            entity.setOuterStatus("已完成");
            entity.setInnerStatus("已完成");
            entity.setQuotedPriceOrderId(o.getQuotedPriceOrderId());
            entity.setQuotedPriceOrderNo(o.getQuotedPriceOrderNo());
            entity.setTurn(o.getTurn());
            return entity;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 更新采购询价合同创建状态
     * @author 伍将
     * @date 2021/3/4
     * @param user: 当前登录用户
     * @param demandId: 需求单id
     * @param awardMemberId: 授标会员id
     * @param awardRoleId: 授标会员角色id
     * @param isCreate 创建合同：0-否，1-是
     * @return 操作结果
     **/
    @Override
    public Wrapper<Void> updateCreateStatus(UserLoginCacheDTO user, Long demandId, Long awardMemberId, Long awardRoleId, Integer isCreate) {

        PurchaseInquiryDO entity = repository.findByDemandMemberIdAndDemandRoleIdAndAwardMemberIdAndAwardRoleIdAndDemandId(
                user.getMemberId(), user.getMemberRoleId(), awardMemberId, awardRoleId, demandId);
        if (null == entity) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_INQUIRY_NOT_EXIST);
        }

        if (CommonBooleanEnum.YES.getCode().equals(entity.getIsCreate()) && CommonBooleanEnum.YES.getCode().equals(isCreate)) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_INQUIRY_IS_CREATE);
        }

        entity.setIsCreate(isCreate);
        entity.setUpdateTime(System.currentTimeMillis());
        repository.saveAndFlush(entity);

        return Wrapper.success();
    }


    /**
     * 检查采购询价合同是否已创建合同
     * @author 伍将
     * @date 2021/3/4
     * @param user: 当前登录用户
     * @param demandId: 需求单id
     * @param awardMemberId: 授标会员id
     * @param awardRoleId: 授标会员角色id
     * @return 操作结果
     **/
    @Override
    public PurchaseInquiryDO checkCreate(UserLoginCacheDTO user, Long demandId, Long awardMemberId, Long awardRoleId) {

        PurchaseInquiryDO entity = repository.findByDemandMemberIdAndDemandRoleIdAndAwardMemberIdAndAwardRoleIdAndDemandId(
                user.getMemberId(), user.getMemberRoleId(), awardMemberId, awardRoleId, demandId);
        if (null == entity) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_INQUIRY_NOT_EXIST);
        }

        if (CommonBooleanEnum.YES.getCode().equals(entity.getIsCreate())) {
            throw new BusinessException(ResponseCode.CONTRACT_PURCHASE_INQUIRY_IS_CREATE);
        }

        return entity;
    }
}
